/**
 * 
 */
package de.htwsaar.smog.dao;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import de.htwsaar.smog.exceptions.MeasurementNotFoundException;
import de.htwsaar.smog.model.Measurement;

/**
 * @author	Thomas Schoenfeld
 * @date	2015-02-14
 * @version	20150214_01
 *
 * This implementation is only necessary to include exception handling.
 * As we decided to support read access solely we do not need it for now. 
 */
@Service
//public class MongoDBMeasurementService implements MeasurementService {
public class MongoDBMeasurementService implements MeasurementRepository {	

	@Autowired
	private MeasurementRepository repo;
	
	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findById(java.lang.String)
	 */
	@Override
	public Measurement findById(String id) {
		return this.findMeasurementByValue(id);		
	}

	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findBySensorId(java.lang.String)
	 */
	@Override
	public List<Measurement> findBySensorId(String sensorId) {
		
		List<Measurement> measurements = repo.findBySensorId(sensorId);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}
	
	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findByLocation(java.lang.String)
	 */
	@Override
	public List<Measurement> findByLocation(String location) {
		
		List<Measurement> measurements = repo.findByLocation(location);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}	
	
	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findByLongitude(java.lang.String)
	 */
	@Override
	public List<Measurement> findByLongitude(String longitude) {
		
		List<Measurement> measurements = repo.findByLongitude(longitude);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}

	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findByLatitude(java.lang.String)
	 */
	@Override
	public List<Measurement> findByLatitude(String latitude) {
		
		List<Measurement> measurements = repo.findByLatitude(latitude);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}

	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findByType(java.lang.String)
	 */
	@Override
	public List<Measurement> findByType(String type) {
		
		List<Measurement> measurements = repo.findByType(type);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}
	
	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findByTime(java.lang.String)
	 */
	@Override
	public List<Measurement> findByTime(String time) {
		
		List<Measurement> measurements = repo.findByTime(time);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}
	
	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findByValue(java.lang.String)
	 */
	@Override
	public List<Measurement> findByValue(int value) {
		
		List<Measurement> measurements = repo.findByValue(value);
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}	
	
	/* (non-Javadoc)
	 * @see de.htwsaar.smog.dao.MeasurementService#findAll()
	 */
	@Override
	public List<Measurement> findAll() {
		
		List<Measurement> measurements = repo.findAll();
		
		if (measurements.isEmpty()) {
			throw new MeasurementNotFoundException();
		}
		
		return measurements;
	}

	@Override
	public Optional<Measurement> findOne(String value) {
		return repo.findOne(value);
	}
	
	// provides exception handling in functional Java 1.8 style
	private Measurement findMeasurementByValue(String value) {
		Optional<Measurement> result = this.findOne(value);
		return result.orElseThrow(() -> new MeasurementNotFoundException(value));
	}
	
}
